# ########################################################################################
#this module defines jetSim objects, which are meant to create, run and manage simulations of 
#turbulent plasma jets, which are carried out in c++ 
# ########################################################################################
import gasMixture
import plasmaTorch 
reload(plasmaTorch )
from plasmaTorch import *
from helpers import *
from numpy import *
import cPickle
import pickle
import subprocess
import scipy
import pdb
from pylab import *
import matplotlib as mpl
#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
#define the jetSim class to handle input/output files for and run plasma jet simulations
#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
class jetSim(object):
	"""this object sets up, handles the input/output files for, 
		and runs plasma jet simulations"""
	
	#constructor to set defaults#
	def __init__(self, torch=None):
		"""
		set default parameters with this method
		"""
		#set and solve the torch model
		if torch!=None:
			self.torch = torch
			self.torch.solve()
		
		#name the simulation by the input conditions
		self.isRun = 0 #flag whether the sim has been run
		
		#default gridDims in mm
		self.dr 			= 		.2e-3
		self.dz 			= 		.5e-3
		self.rMax 		= 		25e-3
		self.zMax 		= 		100e-3
		self.nTheta 	= 		1
				
		
		self.setR()
		self.setGridStr()
	
	#--------------------------------------------- setters/getters
	def changeTorch(self, torch):
		"""
		pass a torch object to swap torches
		"""
		self.torch = torch
		self.torch.solve()
		self.isRun = 0 #flag whether the sim has been run
		
	def setR(self):
		"""
		use the grid parameters to set up the radial mesh
		"""
		self.r = arange(self.dr/2, self.rMax+self.dr/2,self.dr)
		
	def setGridStr(self):
		"""
		form the list of strings describing the grid geometry
		"""
		self.gridStr = [	'dr', str(self.dr), 
			'dz', str(self.dz),
			'rMax', str(self.rMax),
			'zMax', str(self.zMax),
			'nTheta', str(self.nTheta)]
		
	def setGeom(self, gridSize):#,  torchFlowrate, torchCurrent, torch, gas, gasStrFn, torchStrFn )
		"""set all the attributes associated with the computational domain: 
		
		Geometric Attributes:
		gridSize - [dr, dz, rMax, zMax, nTheta], gives the dimensions of the grid 
						[radialStep, axialStep, maxRadius, maxAxial, numAngularDivisions] 
		"""
	
		#set the mesh size and extent first
		nGridParameters = range(array(gridSize).size)	
		
		for i in nGridParameters:
			if i == 0:
				self.dr = gridSize[nGridParameters[i]]
			elif i == 1:
				self.dz = gridSize[nGridParameters[i]]
			elif i == 2:
				self.rMax = gridSize[nGridParameters[i]]
			elif i == 3:
				self.zMax = gridSize[nGridParameters[i]]
			elif i == 4:
				self.nTheta = gridSize[nGridParameters[i]]
					
		self.setR()
		self.setGridStr()
		
	
	def simName(self):
		"""
		name the sim by the input conditions
		"""
		return self.torch.inputConditionsString
	#-------------------------------------------------------------------

	#\\\\\\\\\\\\\\\\\\\\\\\\ file i/o#
	def writeInputFile(self):
		"""
		write the input file using current parameters
		"""
		#make an input file
		f = open(self.simName()+".inp",'w')
		
		#summon strings describing the torch exit conditions 
		tStr = self.torch.jetInpFileStr(self.r)
		
		#write the gas properties to a file and return the filename
		gStr = self.torch.gas.write()
		
		#write everything we need to know about the sim to the input file
		bigStr = (self.gridStr + 
						["\nTin "+ str(self.r.size)] +tStr[1]+
						["\nVin "  + str(self.r.size)] + tStr[2] + 
						["\ngasFile"] + [gStr])
		for s in bigStr:
			f.write(s+'\n')
		f.close()
		
	def readOutputFiles(self):
		"""
		read in the solution from output files generated by the simulation
		"""
		f = open('r.txt')
		r = array(double(f.readline().replace('\n','').replace('[','').replace(']','').replace('(',' ').replace(')','').replace(',',' ').split())) 
		r = delete(r,0)
		f.close()
		
		f = open('z.txt')
		z = array(double(f.readline().split()))
		f.close 
		
		f = open('v.txt')
		v = array([array(double(ss.replace('\n','').replace('[','').replace(']','').replace('(',' ').replace(')','').replace(',',' ').split())) 
			for ss in f.readlines()])
		v = delete(v,0,1)
		f.close()
		
		f = open('t.txt')
		T = array([array(double(ss.replace('\n','').replace('[','').replace(']','').replace('(',' ').replace(')','').replace(',',' ').split())) 
			for ss in f.readlines()])
		T= delete(T,0,1)
		f.close()
		
		self.outputTuple = (r,z,T,v)
	
	def writeSummary(self):
		"""
		write the output of the simulation to a single text file
		"""
		r,z,T,V = self.outputTuple
		f = open(self.simName()+".out",'w')
		
		f.write("radial mesh, m \n")
		f.write(str(r).replace('\n','').replace('[','').replace(']','')+'\n\n')
		
		f.write("\n axial mesh, m \n")
		f.write(str(z).replace('\n','').replace('[','').replace(']','')+'\n\n')
		
		f.write("\n temperature field, K, radial direction in columns  \n")
		for i in range(T.shape[0]):
			f.write(str(T[i]).replace('\n','').replace('[','').replace(']','')+'\n')
	
		f.write("\n velocity field, m/s, radial direction in columns  \n")
		for i in range(V.shape[0]):
			f.write(str(V[i]).replace('\n','').replace('[','').replace(']','')+'\n')
		
		f.write("\n gas properties, rows: temperature, conductivity, density, enthalpy, specific heat, viscosity  \n")
		for i in range(self.torch.gas.mixProps.shape[0]):
			f.write(str(self.torch.gas.mixProps[i]).replace('\n','').replace('[','').replace(']','')+'\n')
		f.close()
		
	def load(self):
		#here we open a file and read in all the variable names
		f=open(self.simName()+".pkl",'rb')
		return cPickle.load(f)
		f.close()
		
	def save(self, simName = None):
		#save the input (output) files using pickle under simName 
		if simName ==None:
			simName = self.simName()
		f = open(simName()+".pkl",'wb')
		cPickle.dump(dict(zip(['radialCoord','axialCoord','temperature','velocity'],
													self.outputTuple)	+ self.torch.stateVector()), 
													f, -1)
		f.close()
	
	#\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
	
	
	#simulation operators#
	def run(self):
		#write an input file and run the sim, then save both output file and input file
		self.writeInputFile()
		subprocess.check_call(['C:\\Documents and Settings\\m.cannamela\\My Documents\\Visual Studio 2008\\Projects\\turbulentJetSimF\\Release\\turbulentJetSimF.exe',
													self.simName()+".inp"])
		self.isRun=1
		self.readOutputFiles()
		self.writeSummary()
		self.save()


	
	
if __name__== "__main__":
	testJet = False
	testField = True
	
	if testJet:
		g = gasMixture()
		g.blend(['argon', 'helium'],[68, 32])

		finkeTorch = ramshawAndChangTorch()
		#finkeTorch.solve()

		pfenderTorch = ramshawAndChangTorch(800, 69, g,'SG100' , array([15000, 1000]))
		#pfenderTorch.solve()
		
		jsAr = jetSim(finkeTorch)
		jsAr.run()
		
		jsHe = jetSim(pfenderTorch)
		jsHe.run()
		
		output = jsAr.load()
	
	if testField:
		pf = plasmaField('..\\pyrticle\\cur-700_flo-50_gas-argon68helium32_make-SG100')
		dpf = dummyField()
		
		print 'plasma density'
		print pf.density(zeros(3))
		
		print 'dummy plasma density'
		print dpf.density(zeros(3))
		
		